import java.util.Random;


public class URLGenerator {
	
	public boolean valid;
	public String text;	
	
	public URLGenerator(String text, boolean valid){
		this.text = text;
		this.valid = valid;
	}
	
	// generate n random authorities
	public static URLGenerator generateAuthority(int prob){
		Random r = new Random();
		Integer num = r.nextInt(10000);
		String numString = num.toString();
		boolean valid;
		String text;
		String[] validAuths = {"www.amazon.com", "0.0.0.0", "255.255.255.255", "google.co.uk", "google.com", numString+".com", "test.edu", "texas.gov", "go.au", "facebook.com", "blah.mil", "random.net", "192.168.1.2", "localhost", "asdsadas.org"}; 
		String[] invalidAuths = {"255.256.256.255", "/..", "/.", ".google.com", ",amazon.com", "1.2.3", "", "blah_blah.org", "rand", "rand/aaa", "google.123", ".123.com", "."+numString+".org", "goog.org1", "google.", "who?me.com"};  
		int val = r.nextInt(prob+1);
		if(val == prob){
			valid = false;
			text = invalidAuths[r.nextInt(invalidAuths.length)];
		}
		else{
			valid = true;
			text = validAuths[r.nextInt(validAuths.length)];
		}
		URLGenerator authority = new URLGenerator(text, valid);
		return authority;
	}
	
	public static URLGenerator generatePort(int prob){
		Random r = new Random();
		Integer randPort = r.nextInt(1024);
		boolean valid;
		String text;
		String[] validPorts = {":80", ":322", ":3", ":22", ":"+randPort.toString()}; // 8080 fails, but I'm not sure if it should pass
		String[] invalidPorts = {":8o8o", ":-22", ":9a", ":-8080"};
		int val = r.nextInt(prob+1);
		if(val == prob){
			valid = false;
			text = invalidPorts[r.nextInt(invalidPorts.length)];
		}
		else{
			valid = true;
			text = validPorts[r.nextInt(validPorts.length)];
		}
		URLGenerator port = new URLGenerator(text, valid);
	return port;
	}
	
	public static URLGenerator generatePath(int prob){
		Random r = new Random();
		boolean valid;
		String text;
		String[] validPaths = { "/test", "/index.php", "/about", "/1", "/contact.php", "/users.json", "/users/23/edit", "/first123", "/second234.php", "/$test", ""};
		String[] invalidPaths = {"//test", "/users//2", "/home/2//edit", "/#/contact.php", "/..", "/../"};
		int val = r.nextInt(prob+1);
		if(val == prob){
			valid = false;
			text = invalidPaths[r.nextInt(invalidPaths.length)];
		}
		else{
			valid = true;
			text = validPaths[r.nextInt(validPaths.length)];
		}
		URLGenerator path = new URLGenerator(text, valid);
		return path;
	}
	
	public static URLGenerator generateQuery(int prob){
		Random r = new Random();
		boolean valid;
		String text;
		String[] validQueries = { "?search=true", "?search=true&name=bob", "?get=true&mail=true", "?123=false", "?search=true&mail=123", "?search=123&me=true","" };
		valid = true;
		text = validQueries[r.nextInt(validQueries.length)];
		URLGenerator query = new URLGenerator(text, valid);
		int rand = r.nextInt(prob+1); // we know any params will fail, so I descreased the probability here to keep the output clean and helpful
		if(rand == 1)
			return query;
		else
			return new URLGenerator("", true); // no query
	}
	
	public static URLGenerator generateFragment(int prob){
		Random r = new Random();
		boolean valid;
		String text;
		String[] validFrags = { "#contact", "#123232", "#00h02m30s", "#", "#!$?/@'" };
		valid = true;
		text = validFrags[r.nextInt(validFrags.length)];
		URLGenerator frag = new URLGenerator(text, valid);
		int rand = r.nextInt(prob + 1); // insert fragment with 50% of Urls
		if(rand == 1)
			return frag;
		else
			return new URLGenerator("", true); // no fragment
	}
	
	// prob = probability of inserting a failing segment. E.g. 10 means 10% of the time, an invalid segment will be added to the url
	public static URLGenerator generateUrl(String providedScheme, int prob){
		boolean valid = true;
		URLGenerator scheme = new URLGenerator(providedScheme, true);
		URLGenerator authority = URLGenerator.generateAuthority(prob);
		if(authority.valid == false) valid = false;
		URLGenerator port = URLGenerator.generatePort(prob);
		if(port.valid == false) valid = false;
		URLGenerator path = URLGenerator.generatePath(prob);
		if(path.valid == false) valid = false;
		URLGenerator query = URLGenerator.generateQuery(100);
		if(query.valid == false) valid = false;
		URLGenerator frag = URLGenerator.generateFragment(2);
		if(frag.valid == false) valid = false;
		
		URLGenerator url = new URLGenerator(scheme.text+authority.text+port.text+path.text+query.text+frag.text, valid);
		return url;
	}
}
